#include <QtGui>
#include "window.h"
#include "globalshortcutmanager.h"
#include "verbRunner.h"

void InputWin::summoned() {
  if (this->isVisible()) {
    this->hide();
  } else {
    // reload results before reverting to recursive mode
    noun->edited("", true);
    noun->makeRecurMode = true;
    this->show();
    activateWindow();
    raise();
    noun->setFocus();
    noun->query->selectAll();
  }
}

void InputWin::verbChanged() {
  toggleAux( checkVerbAux(verb->getSelectedPath()) );
}

void InputWin::nounChanged() {
  if (noun->hasSelection()) {
    verb->typeFilter = getNounType((ResultItem*)noun->resultsBox->currentItem());
    verb->edited(); // Don't reload every time
  }
}

void InputWin::toggleAux(bool show) {
  auxOn = show;
  QRect space = QApplication::desktop()->availableGeometry();
  if (show) {
    resize(space.width()*0.95, this->height()); //styling
    aux->show();
    aux->edited(aux->query->text(), true);
  } else if (!show) {
    resize(space.width()*0.95*2/3.0, this->height()); //styling
    aux->hide();
  }
}

void InputWin::entered() {
  emit this->enter();
  if (noun->hasSelection() && verb->hasSelection() && (!auxOn || aux->hasSelection()) ) {
    run();
  }
  
  // Do not clear text on enter: keep previous result in refreshed list
  /*noun->query->setText("");
  verb->query->setText("");
  aux->query->setText("");*/
  summoned();
}

void InputWin::run() {
  string cmd = "\"" + verb->getSelectedPath() + "\" \"" + noun->getSelectedPath() + "\""; // to prevent spaces, should write better method
  if (auxOn) cmd += " \"" + aux->getSelectedPath() + "\"";
  verbRunner::run(cmd);
}

InputWin::InputWin(QWidget *parent) : QWidget(parent) {
  
  setAttribute(Qt::WA_TranslucentBackground);
  setWindowFlags(Qt::FramelessWindowHint);
  
  QRect space = QApplication::desktop()->availableGeometry();
  resize(space.width()*0.95, space.height()*.5); //styling
  
  noun = new Word(this, Word::NOUN);
  verb = new Word(this, Word::VERB);
  aux = new Word(this, Word::AUX);
  
  this->move(space.width()*.025, space.height()*.1);
  verb->move(this->width()/3.0, 0); //styling
  aux->move(this->width()*2/3.0, 0); //styling
  
  toggleAux(false);
  
  #ifdef __APPLE__
  QMenuBar * menubar = new QMenuBar(this);
  QMenu * FileMenu = menubar->addMenu("File");
  FileMenu->addAction("Close", this, SLOT(close()), QKeySequence(tr("Ctrl+W")));
  FileMenu->addAction("Quit", qApp, SLOT(quit()));
  QMenu * ToolsMenu = menubar->addMenu("Tools");
  ToolsMenu->addAction("Preferences", this, SLOT(showPref()), QKeySequence(tr("Ctrl+P")));
  #endif

  QSystemTrayIcon * trayIcon = new QSystemTrayIcon(this);
  trayIcon->setIcon(QIcon(":/icon/bigIcon.png"));
  QMenu * trayIconMenu = new QMenu(this);
  trayIconMenu->addAction("Preferences", this, SLOT(showPref()));
  trayIconMenu->addAction("Quit", qApp, SLOT(quit()));
  trayIcon->setContextMenu(trayIconMenu);
  trayIcon->show();
  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivation(QSystemTrayIcon::ActivationReason)));

  db = QSqlDatabase::addDatabase("QSQLITE");
  db.setDatabaseName(settings.value("dbPath").toString());
  if (!db.open()) {
    trayIcon->showMessage("Database could not be opened", "ki will not be able to learn from your input");
  }
  
  GlobalShortcutManager::instance()->connect(QKeySequence(settings.value("hotkeyMod").toInt()+settings.value("hotkey").toInt()), this, SLOT(summoned()));
  connect(verb, SIGNAL(newSelected()), this, SLOT(verbChanged()));
  connect(noun, SIGNAL(newSelected()), this, SLOT(nounChanged()));
  qApp->installEventFilter(this);
  
  // Reload verbs
  nounChanged();
}

bool InputWin::checkVerbAux(string path) {
  string cmd = "\"" + path + "\" -x"; // to prevent spaces, should write better method
  /*FILE *output = popen(cmd.c_str(), "r");
  char buffer[2];
  fgets(buffer, 2, output);
  pclose(output);
  if (string(buffer) == "1") {*/
  int message = verbRunner::run(cmd).toInt();
  if (message == 0 || message == 1 || message == 2) {
    aux->typeFilter = message;
    return message;
  }
  return false;
}

int InputWin::getNounType(ResultItem * item) {
  return item->type;
}

bool InputWin::eventFilter(QObject * obj, QEvent * e) {
  // Summon on activation if hidden
  if (obj == qApp) {
    if (e->type() == QEvent::ApplicationActivate && !this->isVisible()) {
      summoned();
    } else if (e->type() == QEvent::ApplicationDeactivate && this->isVisible()) {
      hide();
    }
  }
  return QWidget::eventFilter(obj, e);
}

void InputWin::showPref() {
  if (!qApp->allWidgets().contains(prefWin)) {
    prefWin = new PrefWindow();
  }
  prefWin->show();
  prefWin->activateWindow();
}

void InputWin::trayActivation(QSystemTrayIcon::ActivationReason reason) {
  if (reason == QSystemTrayIcon::Trigger && !this->isVisible()) {
    summoned();
  }
}

void InputWin::keyPressEvent(QKeyEvent * e) {
  switch(e->key()) {
    case Qt::Key_Escape: hide();
                         break;
    default: QWidget::keyPressEvent(e);
  }
}
